package com.hao.link;

/**
 * TODO
 *
 * @author 97472
 * @version 1.0
 * @date 2021/4/19 10:16
 */
public class MyDoublyLinkListImpl<T> implements MyDoublyLinkList<T>{
    /**
     * 链表的大小
     */
    private Integer size = 0;
    /**
     * 链表的头节点
     */
    private Node<T> first;
    /**
     * 链表的尾节点
     */
    private Node<T> last;
    public T getFirst() {
        return first == null?null:first.t;
    }

    public T getLast() {
        return last == null?null:last.t;
    }

    public void add(T t) {
        Node<T> newNode = new Node<T>(t, null, null);
        boolean hasFirst = first != null;
        boolean hasLast = last != null;
        if (hasFirst){
            if (hasLast){
                last.nextNode = newNode;
                newNode.preNode = last;
            }else {
                first.nextNode = newNode;
                newNode.preNode = first;
            }
            last = newNode;
        }else {
            first = newNode;
        }
        size++;
    }

    public void delete(int index) {
        isOut(index);
        Node<T> delNode = getNodeByIndex(index);
        Node<T> pre = delNode.preNode;
        Node<T> next = delNode.nextNode;
        if (pre == null){
            first = next;
        }else {
            pre.nextNode = next;
            delNode.preNode = null;
        }

        if (next == null){
            last = pre;
        }else {
            next.preNode = pre;
            delNode.nextNode = null;
        }
        delNode.t = null;
        size--;
    }

    public void update(int index, T t) {
        isOut(index);
        Node<T> node = getNodeByIndex(index);
        Node<T> pre = node.preNode;
        Node<T> next = node.nextNode;
        Node<T> updateNode = new Node<T>(t, next, pre);
        if (pre == null){
            first = updateNode;
        }else {
            pre.nextNode = updateNode;
            node.preNode = null;
        }

        if (next == null){
            last = updateNode;
        }else {
            next.preNode = updateNode;
            node.nextNode = null;
        }
        node.t = null;
    }

    public void insert(int index, T t) {
        isOut(index);
        Node<T> node = getNodeByIndex(index);
        Node<T> pre = node.preNode;
        Node<T> insertNode = new Node<T>(t, node, pre);
        if (pre == null){
            first = insertNode;
        }else {
            pre.nextNode = insertNode;
        }
        node.preNode = insertNode;
        size++;
    }

    public T get(int index) {
        return getNodeByIndex(index).t;
    }

    public Integer size() {
        return size;
    }

    public Boolean isEmpty() {
        return size == 0;
    }
    private Node<T> getNodeByIndex(int index){
        isOut(index);
        Node<T> temp = first;
        for (int i = 0; i < index; i++) {
            temp = temp.nextNode;
        }
        return temp;
    }
    private void isOut(int index){
        boolean isOut = index >= size;
        if (isOut){
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    @Override
    public String toString() {
        String out = "";
        Node<T> temp = first;
        for (int i = 0; i < size; i++) {
            out = out + "  " + temp.t;
            temp = temp.nextNode;
        }
        return out;
    }
    /**
     * @Author a'hao
     * @Description //TODO 这是链表的节点
     * @Date 16:56 2021/4/18
     * @Param
     * @return
     **/
    class Node<T>{
        /**
         * 用户要存放的数据
         **/
        T t;
        /**
         * 下一个节点的地址
         **/
        Node<T> nextNode;
        /**
         * 上个节点地址
         */
        Node<T> preNode;

        public Node(T t, Node<T> nextNode,Node<T> preNode) {
            this.t = t;
            this.nextNode = nextNode;
            this.preNode = preNode;
        }
    }
}
